/*
 * Copyright 2025 RestfulToolX Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.welson.restfultoolx.ui;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiClass;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.JBTextField;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.util.ui.JBUI;
import com.welson.restfultoolx.model.ApiInfo;
import com.welson.restfultoolx.model.SearchOptions;
import com.welson.restfultoolx.service.ControllerScannerService;
import com.welson.restfultoolx.service.SearchEngineService;
import com.welson.restfultoolx.service.SearchHistoryService;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.stream.Collectors;

/**
 * 快速搜索对话框
 * 提供实时搜索和快速导航功能
 */
public class QuickSearchDialog extends DialogWrapper {
    private static final int SEARCH_DELAY_MS = 300;
    
    private final Project project;
    private final ControllerScannerService scannerService;
    private final SearchEngineService searchService;
    private final SearchHistoryService historyService;
    
    private JBTextField searchField;
    private JBList<ApiInfo> resultList;
    private DefaultListModel<ApiInfo> listModel;
    private JPanel contentPanel;
    
    // HTTP方法筛选复选框
    private JBCheckBox getCheckBox;
    private JBCheckBox postCheckBox;
    private JBCheckBox putCheckBox;
    private JBCheckBox deleteCheckBox;
    private JBCheckBox optionsCheckBox;
    
    // 钉住功能
    private JBCheckBox pinCheckBox;
    private boolean isPinned = false;
    
    private Timer searchTimer;
    private List<ApiInfo> allApis;
    private BulkFileListener fileListener;
    private volatile boolean needsRefresh = false;
    private KeyEventDispatcher globalKeyListener;
    
    public QuickSearchDialog(@NotNull Project project) {
        super(project, false); // 设置为非模态
        this.project = project;
        this.scannerService = project.getService(ControllerScannerService.class);
        this.searchService = project.getService(SearchEngineService.class);
        this.historyService = project.getService(SearchHistoryService.class);
        
        setTitle("请输入一个API路径"); // 简化标题
        setModal(false);
        setResizable(false); // 禁止调整大小
        init();
        
        // 异步加载API数据
        loadApisAsync();
        
        // 设置文件变化监听器
        setupFileListener();
        
        // 设置全局Alt键监听器
        setupGlobalKeyListener();
    }
    
    @Override
    protected @Nullable JComponent createCenterPanel() {
        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.setPreferredSize(new Dimension(380, 40)); // 更紧凑的初始尺寸
        
        // 创建搜索面板
        JPanel searchPanel = createSearchPanel();
        mainPanel.add(searchPanel, BorderLayout.NORTH);
        
        // 创建简化的结果列表 - 初始状态隐藏
        contentPanel = createSimpleContentPanel();
        contentPanel.setVisible(false);
        mainPanel.add(contentPanel, BorderLayout.CENTER);
        
        return mainPanel;
    }
    
    @Override
    public void show() {
        super.show();
        // 设置对话框位置到IDEA主窗口所在显示器的三分之一处
        Window window = getWindow();
        if (window != null) {
            positionDialogRelativeToIdeaWindow(window);
        }
    }
    
    private void positionDialogRelativeToIdeaWindow(Window dialogWindow) {
        // 获取IDEA主窗口
        Window ideaWindow = WindowManager.getInstance().getFrame(project);
        if (ideaWindow != null) {
            // 获取IDEA窗口所在的屏幕区域
            GraphicsConfiguration gc = ideaWindow.getGraphicsConfiguration();
            Rectangle screenBounds = gc.getBounds();
            
            Dimension dialogSize = dialogWindow.getSize();
            
            // 计算相对于IDEA窗口所在屏幕的位置
            int x = screenBounds.x + (screenBounds.width - dialogSize.width) / 2;
            int y = screenBounds.y + screenBounds.height / 3 - dialogSize.height / 2;
            
            dialogWindow.setLocation(x, y);
        } else {
            // 如果无法获取IDEA窗口，使用默认屏幕定位
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            Dimension windowSize = dialogWindow.getSize();
            int x = (screenSize.width - windowSize.width) / 2;
            int y = screenSize.height / 3 - windowSize.height / 2;
            dialogWindow.setLocation(x, y);
        }
    }
    
    private JPanel createSearchPanel() {
        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.setBorder(JBUI.Borders.empty(2, 2, 2, 2));
        
        // 创建顶部搜索行（搜索框 + 筛选按钮 + 钉住按钮）
        JPanel topPanel = new JPanel(new BorderLayout());
        
        // 搜索框
        searchField = new JBTextField();
        searchField.setToolTipText("输入API路径、方法名或类名进行搜索 (F5刷新缓存)");
        searchField.setFont(searchField.getFont().deriveFont(13f));
        
        // 设置上次搜索的内容
        String lastQuery = historyService.getLastSearchQuery();
        if (!lastQuery.isEmpty()) {
            searchField.setText(lastQuery);
            searchField.selectAll();
            SwingUtilities.invokeLater(() -> scheduleSearch());
        }
        
        // 添加实时搜索功能
        searchField.getDocument().addDocumentListener(new DocumentAdapter() {
            @Override
            protected void textChanged(@NotNull DocumentEvent e) {
                scheduleSearch();
            }
        });
        
        // 添加键盘导航
        searchField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                handleSearchFieldKeyPress(e);
            }
        });
        
        // 添加失去焦点时关闭对话框的功能（仅在未钉住时）
        searchField.addFocusListener(new java.awt.event.FocusAdapter() {
            @Override
            public void focusLost(java.awt.event.FocusEvent e) {
                if (!isPinned) {
                    SwingUtilities.invokeLater(() -> {
                        Component opposite = e.getOppositeComponent();
                        if (opposite == null || !SwingUtilities.isDescendingFrom(opposite, getContentPanel())) {
                            close(CANCEL_EXIT_CODE);
                        }
                    });
                }
            }
        });
        
        // 右侧按钮面板（只保留钉住按钮）
        JPanel rightPanel = new JPanel(new BorderLayout());
        
        // 钉住按钮
        pinCheckBox = new JBCheckBox("📌");
        pinCheckBox.setToolTipText("钉住对话框");
        pinCheckBox.setPreferredSize(new Dimension(24, 24));
        pinCheckBox.addActionListener(e -> {
            isPinned = pinCheckBox.isSelected();
            if (isPinned) {
                pinCheckBox.setToolTipText("取消钉住");
            } else {
                pinCheckBox.setToolTipText("钉住对话框");
            }
        });
        
        // 使用BorderLayout.CENTER让钉住按钮垂直居中对齐
        rightPanel.add(pinCheckBox, BorderLayout.CENTER);
        rightPanel.setBorder(JBUI.Borders.empty(0, 2, 0, 2)); // 添加左右边距
        
        topPanel.add(searchField, BorderLayout.CENTER);
        topPanel.add(rightPanel, BorderLayout.EAST);
        
        // 筛选面板（保持一直显示）
        JPanel filterPanel = createFilterPanel();
        filterPanel.setVisible(true);
        
        mainPanel.add(topPanel, BorderLayout.NORTH);
        mainPanel.add(filterPanel, BorderLayout.CENTER);
        
        return mainPanel;
    }
    
    private JPanel createFilterPanel() {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 2));
        panel.setBorder(JBUI.Borders.empty(2, 0, 2, 0));
        
        // 创建HTTP方法复选框
        getCheckBox = new JBCheckBox("GET", true);
        postCheckBox = new JBCheckBox("POST", true);
        putCheckBox = new JBCheckBox("PUT", true);
        deleteCheckBox = new JBCheckBox("DELETE", true);
        optionsCheckBox = new JBCheckBox("OPTIONS", true);
        
        // 设置复选框样式
        JBCheckBox[] checkBoxes = {getCheckBox, postCheckBox, putCheckBox, deleteCheckBox, optionsCheckBox};
        for (JBCheckBox checkBox : checkBoxes) {
            checkBox.setFont(checkBox.getFont().deriveFont(11f));
            checkBox.addActionListener(e -> scheduleSearch());
        }
        
        // 快捷按钮
        JButton allButton = new JButton("All");
        JButton noneButton = new JButton("None");
        JButton invertButton = new JButton("Invert");
        
        JButton[] buttons = {allButton, noneButton, invertButton};
        for (JButton button : buttons) {
            button.setFont(button.getFont().deriveFont(10f));
            button.setMargin(JBUI.insets(1, 4));
            button.setPreferredSize(new Dimension(40, 20));
        }
        
        allButton.addActionListener(e -> {
            for (JBCheckBox cb : checkBoxes) cb.setSelected(true);
            scheduleSearch();
        });
        
        noneButton.addActionListener(e -> {
            for (JBCheckBox cb : checkBoxes) cb.setSelected(false);
            scheduleSearch();
        });
        
        invertButton.addActionListener(e -> {
            for (JBCheckBox cb : checkBoxes) cb.setSelected(!cb.isSelected());
            scheduleSearch();
        });
        
        panel.add(new JLabel("Filter:"));
        panel.add(getCheckBox);
        panel.add(postCheckBox);
        panel.add(putCheckBox);
        panel.add(deleteCheckBox);
        panel.add(optionsCheckBox);
        panel.add(Box.createHorizontalStrut(10));
        panel.add(allButton);
        panel.add(noneButton);
        panel.add(invertButton);
        
        return panel;
    }
    

    
    private JPanel createSimpleContentPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(JBUI.Borders.empty(0, 2, 2, 2)); // 减小两侧padding
        
        // 创建结果列表
        listModel = new DefaultListModel<>();
        resultList = new JBList<>(listModel);
        resultList.setCellRenderer(new SimpleApiListCellRenderer());
        resultList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        // 添加双击监听器
        resultList.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    navigateToSelectedApi();
                }
            }
        });
        
        // 添加键盘导航
        resultList.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    navigateToSelectedApi();
                }
            }
        });
        
        JBScrollPane scrollPane = new JBScrollPane(resultList);
        scrollPane.setBorder(null); // 去除滚动面板边框
        panel.add(scrollPane, BorderLayout.CENTER);
        
        return panel;
    }
    

    

    
    private void scheduleSearch() {
        if (searchTimer != null) {
            searchTimer.stop();
        }
        
        searchTimer = new Timer(SEARCH_DELAY_MS, e -> performSearch());
        searchTimer.setRepeats(false);
        searchTimer.start();
    }
    
    private void performSearch() {
        String query = searchField.getText().trim();
        
        // 获取当前窗口位置，避免重新定位时的跳动
        Window window = getWindow();
        Point currentLocation = window != null ? window.getLocation() : null;
        
        if (query.isEmpty()) {
            // 输入为空时隐藏结果区域，恢复到极简状态
            contentPanel.setVisible(false);
            updateResultList(null);
            // 筛选面板始终显示，调整对话框高度
            getContentPanel().setPreferredSize(new Dimension(450, 70));
            pack();
            
            // 保持位置不变
            if (window != null && currentLocation != null) {
                window.setLocation(currentLocation);
            }
            return;
        }
        
        // 显示结果区域，扩展对话框尺寸
        contentPanel.setVisible(true);
        // 筛选面板始终显示，调整对话框高度
        getContentPanel().setPreferredSize(new Dimension(550, 550));
        pack();
        
        // 保持位置稳定，只在首次展开时重新定位
        if (window != null) {
            if (currentLocation != null) {
                // 如果已有位置，保持不变
                window.setLocation(currentLocation);
            } else {
                // 首次展开时才重新定位
                positionDialogRelativeToIdeaWindow(window);
            }
        }
        
        if (allApis == null || allApis.isEmpty()) {
            updateResultList(List.of());
            return;
        }
        
        // 执行搜索
        SearchOptions options = SearchOptions.createQuick();
        List<ApiInfo> results = searchService.search(query, options);
        
        // 应用HTTP方法筛选
        results = applyHttpMethodFilter(results);
        
        updateResultList(results);
    }
    
    private List<ApiInfo> applyHttpMethodFilter(List<ApiInfo> results) {
        // 获取选中的HTTP方法
        Set<String> selectedMethods = new HashSet<>();
        if (getCheckBox.isSelected()) selectedMethods.add("GET");
        if (postCheckBox.isSelected()) selectedMethods.add("POST");
        if (putCheckBox.isSelected()) selectedMethods.add("PUT");
        if (deleteCheckBox.isSelected()) selectedMethods.add("DELETE");
        if (optionsCheckBox.isSelected()) selectedMethods.add("OPTIONS");
        
        // 如果没有选中任何方法，返回空列表
        if (selectedMethods.isEmpty()) {
            return List.of();
        }
        
        // 如果选中了所有方法，直接返回原结果
        if (selectedMethods.size() == 5) {
            return results;
        }
        
        // 筛选结果
        return results.stream()
                .filter(api -> {
                    String httpMethod = api.getHttpMethod();
                    return httpMethod != null && selectedMethods.contains(httpMethod.toUpperCase());
                })
                .collect(Collectors.toList());
    }
    
    private void updateResultList(List<ApiInfo> results) {
        SwingUtilities.invokeLater(() -> {
            listModel.clear();
            if (results != null) {
                for (ApiInfo api : results) {
                    listModel.addElement(api);
                }
                
                // 自动选择第一个结果并确保可见
                if (!results.isEmpty()) {
                    resultList.setSelectedIndex(0);
                    resultList.ensureIndexIsVisible(0);
                }
            }
        });
    }
    

    
    private void handleSearchFieldKeyPress(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_DOWN:
                if (listModel.getSize() > 0) {
                    resultList.requestFocus();
                    // 如果已经选中第一项，移动到第二项；否则选中第一项
                    int currentIndex = resultList.getSelectedIndex();
                    if (currentIndex == 0 && listModel.getSize() > 1) {
                        resultList.setSelectedIndex(1);
                    } else {
                        resultList.setSelectedIndex(0);
                    }
                }
                e.consume();
                break;
            case KeyEvent.VK_ENTER:
                if (listModel.getSize() > 0) {
                    // 保存搜索历史
                    String query = searchField.getText().trim();
                    if (!query.isEmpty()) {
                        historyService.saveSearchQuery(query);
                    }
                    
                    resultList.setSelectedIndex(0);
                    navigateToSelectedApi();
                }
                e.consume();
                break;
            case KeyEvent.VK_F5:
                // F5刷新API缓存
                refreshApis();
                e.consume();
                break;
            case KeyEvent.VK_ESCAPE:
                close(CANCEL_EXIT_CODE);
                e.consume();
                break;
        }
    }
    
    private void navigateToSelectedApi() {
        ApiInfo selectedApi = resultList.getSelectedValue();
        if (selectedApi == null) {
            return;
        }
        
        // 保存搜索历史
        String query = searchField.getText().trim();
        if (!query.isEmpty()) {
            historyService.saveSearchQuery(query);
        }
        
        // 检查项目状态
        if (project.isDisposed()) {
            showNavigationError("项目已关闭，无法跳转");
            return;
        }
        
        PsiMethod psiMethod = selectedApi.getPsiMethod();
        if (psiMethod == null) {
            showNavigationError("无法找到对应的方法，请尝试刷新索引 (F5)");
            return;
        }
        
        // 检查PsiElement是否有效
        if (!psiMethod.isValid()) {
            // PsiElement失效，尝试重新查找
            psiMethod = findPsiMethodByApiInfo(selectedApi);
            if (psiMethod == null || !psiMethod.isValid()) {
                showNavigationError("方法引用已失效，请尝试刷新索引 (F5)");
                return;
            }
            // 更新ApiInfo中的PsiMethod引用
            selectedApi.setPsiMethod(psiMethod);
        }
        
        // 导航到源代码
        try {
            if (psiMethod instanceof NavigatablePsiElement) {
                ((NavigatablePsiElement) psiMethod).navigate(true);
                close(OK_EXIT_CODE);
            } else {
                showNavigationError("无法导航到该方法");
            }
        } catch (Exception e) {
            showNavigationError("导航失败: " + e.getMessage());
        }
    }
    
    /**
     * 根据ApiInfo重新查找PsiMethod
     * 用于处理PsiElement失效的情况
     */
    private PsiMethod findPsiMethodByApiInfo(ApiInfo apiInfo) {
        if (apiInfo.getClassName() == null || apiInfo.getMethodName() == null) {
            return null;
        }
        
        try {
            // 通过类名查找PsiClass
            PsiClass psiClass = JavaPsiFacade.getInstance(project)
                    .findClass(apiInfo.getClassName(), GlobalSearchScope.projectScope(project));
            
            if (psiClass == null || !psiClass.isValid()) {
                return null;
            }
            
            // 查找对应的方法
            PsiMethod[] methods = psiClass.findMethodsByName(apiInfo.getMethodName(), false);
            for (PsiMethod method : methods) {
                if (method.isValid() && isMatchingMethod(method, apiInfo)) {
                    return method;
                }
            }
        } catch (Exception e) {
            // 忽略查找过程中的异常
        }
        
        return null;
    }
    
    /**
     * 检查方法是否匹配ApiInfo
     */
    private boolean isMatchingMethod(PsiMethod method, ApiInfo apiInfo) {
        // 简单匹配：方法名相同且有相应的Spring注解
        if (!method.getName().equals(apiInfo.getMethodName())) {
            return false;
        }
        
        // 检查是否有Spring Web注解
        return method.hasAnnotation("org.springframework.web.bind.annotation.RequestMapping") ||
               method.hasAnnotation("org.springframework.web.bind.annotation.GetMapping") ||
               method.hasAnnotation("org.springframework.web.bind.annotation.PostMapping") ||
               method.hasAnnotation("org.springframework.web.bind.annotation.PutMapping") ||
               method.hasAnnotation("org.springframework.web.bind.annotation.DeleteMapping") ||
               method.hasAnnotation("org.springframework.web.bind.annotation.PatchMapping");
    }
    
    /**
     * 显示导航错误信息
     */
    private void showNavigationError(String message) {
        SwingUtilities.invokeLater(() -> {
            JOptionPane.showMessageDialog(
                this.getContentPanel(),
                message,
                "导航失败",
                JOptionPane.WARNING_MESSAGE
            );
        });
    }
    
    private void loadApisAsync() {
        // 在后台线程中扫描API
        scannerService.scanProjectAsync(project, () -> {
            allApis = scannerService.scanProject(project);
            
            // 构建搜索索引
            searchService.buildIndex(allApis);
            
            SwingUtilities.invokeLater(() -> {
                // 初始状态不显示任何结果，只有输入时才显示
                updateResultList(null);
                
                // 聚焦到搜索框
                searchField.requestFocus();
                
                // 重置刷新标志
                needsRefresh = false;
            });
        });
    }
    
    /**
     * 设置文件变化监听器
     */
    private void setupFileListener() {
        fileListener = new BulkFileListener() {
            @Override
            public void after(@org.jetbrains.annotations.NotNull java.util.List<? extends VFileEvent> events) {
                boolean shouldRefresh = false;
                
                for (VFileEvent event : events) {
                    if (event instanceof VFileCreateEvent || 
                        event instanceof VFileDeleteEvent || 
                        event instanceof VFileContentChangeEvent) {
                        
                        String filePath = event.getPath();
                        // 检查是否是Java文件且可能包含Controller
                        if (filePath != null && filePath.endsWith(".java")) {
                            shouldRefresh = true;
                            break;
                        }
                    }
                }
                
                if (shouldRefresh && !needsRefresh) {
                    needsRefresh = true;
                    // 延迟刷新，避免频繁更新
                    ApplicationManager.getApplication().invokeLater(() -> {
                        // 使用延迟执行，确保文件系统变更完全完成
                        Timer delayTimer = new Timer(1000, e -> {
                            if (needsRefresh) {
                                refreshApisInBackground();
                            }
                        });
                        delayTimer.setRepeats(false);
                        delayTimer.start();
                    });
                }
            }
        };
        
        // 注册监听器
        ApplicationManager.getApplication().getMessageBus()
            .connect(getDisposable())
            .subscribe(VirtualFileManager.VFS_CHANGES, fileListener);
    }
    
    /**
     * 刷新API缓存
     */
    private void refreshApis() {
        // 清空缓存
        scannerService.refreshCache(project);
        searchService.clearIndex();
        
        // 重新加载
        loadApisAsync();
    }
    
    /**
     * 在后台刷新API，避免阻塞UI
     */
    private void refreshApisInBackground() {
        if (needsRefresh) {
            needsRefresh = false; // 立即重置标志，避免重复刷新
            refreshApis();
        }
    }
    
    /**
     * 设置全局Alt键监听器
     * 当按下Alt键时，聚焦到搜索框
     */
    private void setupGlobalKeyListener() {
        globalKeyListener = new KeyEventDispatcher() {
            @Override
            public boolean dispatchKeyEvent(KeyEvent e) {
                // 只处理按键按下事件，避免重复触发
                if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_ALT) {
                    // 检查对话框是否可见且搜索框存在
                    if (isVisible() && searchField != null) {
                        SwingUtilities.invokeLater(() -> {
                            searchField.requestFocus();
                            searchField.selectAll();
                        });
                    }
                }
                return false; // 不消费事件，让其他组件也能处理
            }
        };
        
        // 注册全局键盘监听器
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(globalKeyListener);
    }
    
    /**
     * 移除全局键盘监听器
     */
    private void removeGlobalKeyListener() {
        if (globalKeyListener != null) {
            KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(globalKeyListener);
            globalKeyListener = null;
        }
    }
    
    @Override
    public void dispose() {
        // 清理全局键盘监听器
        removeGlobalKeyListener();
        super.dispose();
    }
    
    @Override
    protected Action @NotNull [] createActions() {
        return new Action[0]; // 不显示任何按钮
    }
    
    @Override
    public @Nullable JComponent getPreferredFocusedComponent() {
        return searchField;
    }
    
    /**
     * 简化的API列表渲染器
     * 只显示HTTP方法和路径，去除复杂的详细信息
     */
    private static class SimpleApiListCellRenderer extends ColoredListCellRenderer<ApiInfo> {
        
        @Override
        protected void customizeCellRenderer(@NotNull JList<? extends ApiInfo> list,
                                             ApiInfo value,
                                             int index,
                                             boolean selected,
                                             boolean hasFocus) {
            if (value == null) {
                return;
            }
            
            // HTTP方法
            String httpMethod = value.getHttpMethod();
            Color methodColor = getHttpMethodColor(httpMethod);
            SimpleTextAttributes methodAttrs = new SimpleTextAttributes(
                SimpleTextAttributes.STYLE_BOLD, methodColor);
            append(String.format("%-6s", httpMethod), methodAttrs);
            
            // 路径
            String path = value.getPath();
            if (path != null && !path.isEmpty()) {
                append(" " + path, SimpleTextAttributes.REGULAR_ATTRIBUTES);
            }
            
            // 简化的类名和方法名
            String className = value.getSimpleClassName();
            String methodName = value.getMethodName();
            if (className != null && methodName != null) {
                String classMethod = String.format(" (%s.%s)", className, methodName);
                append(classMethod, SimpleTextAttributes.GRAYED_SMALL_ATTRIBUTES);
            }
        }
        
        /**
         * 根据HTTP方法获取对应的颜色
         */
        private Color getHttpMethodColor(String httpMethod) {
            if (httpMethod == null) {
                return Color.GRAY;
            }
            
            switch (httpMethod.toUpperCase()) {
                case "GET":
                    return new Color(0, 128, 0); // 绿色
                case "POST":
                    return new Color(255, 165, 0); // 橙色
                case "PUT":
                    return new Color(0, 0, 255); // 蓝色
                case "DELETE":
                    return new Color(255, 0, 0); // 红色
                case "PATCH":
                    return new Color(128, 0, 128); // 紫色
                default:
                    return Color.GRAY;
            }
        }
    }
}